package ar.frba.utn.diseñosistemas.Tests.TP3;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;

import org.junit.Before;
import org.junit.Test;

import ar.frba.utn.diseñosistemas.TP2.*;

public class TestReserva {

	Usuario gratuito;
	Usuario vip;
	Usuario standar;
	
	ArrayList<Asiento> listaAsientosAReservar;
	ArrayList<Asiento> listaAsientosSobreReservados;
	ArrayList<Asiento> listaAsientosAComprar;
	ArrayList<Asiento> listaAsientosReservados;
	
	@Before
	public void setUp(){
		
		// AEROLINEA MOCK PARA LOS DISINTOS ASIENTOS DEL TEST
		Aerolinea aerolineaMock = new AerolineaMock(); 
		
		// USUARIOS PARA LOS DISTINTOS TEST
		this.gratuito = new Usuario("Matias","Ieno","30654007",new Gratuito(gratuito));
		this.vip = new Usuario("Marcos","Lopez","34432567",new VIP(vip));
		this.standar = new Usuario("Juan","Gutierrez","32000112",new Standar(standar));	
		
		// LISTA PARA LOS TEST DE LA ACCION RESERVAR
		Asiento asiento1 = new Asiento("EA342", "412", 1000023, Clase.Primera, Ubicacion.Centro, EstadoAsiento.Disponible, null, null, null,null, aerolineaMock,"EZE", "PRY");
		Asiento asiento2 = new Asiento("EA341", "411", 3000, Clase.Turista, Ubicacion.Ventanilla, EstadoAsiento.Disponible, null, null, null,null, aerolineaMock,"EZE", "PRY");
		this.listaAsientosAReservar = new ArrayList<Asiento>();
		this.listaAsientosAReservar.add(asiento1);
		this.listaAsientosAReservar.add(asiento2);
		
		// LISTA PARA EL TEST DE RESERVA SOBRERESERVADA
		Asiento asiento3 = new Asiento("EA343", "410", 26271, Clase.Ejecutivo, Ubicacion.Pasillo, EstadoAsiento.Disponible, null, null, null,null, aerolineaMock,"EZE", "PRY");
		this.listaAsientosSobreReservados = new ArrayList<Asiento>();
		this.listaAsientosSobreReservados.add(asiento3);
		
		// LISTA PARA EL TEST COMPRA DE ASIENTO
		Asiento asiento4 = new Asiento("EA345", "439", 23423, Clase.Primera, Ubicacion.Pasillo, EstadoAsiento.Disponible, null, null, null,null, aerolineaMock,"EZE", "PRY");
		this.listaAsientosAComprar = new ArrayList<Asiento>();
		this.listaAsientosAComprar.add(asiento4);
		
		// ASIENTO PARA EL TEST DE TRANSFERENCIA DE RESERVA
		Asiento asientoSobreReservado = new Asiento("EA312", "431", 217781, Clase.Ejecutivo, Ubicacion.Centro, EstadoAsiento.Disponible, null, null, null,null, aerolineaMock,"EZE", "PRY");
		this.listaAsientosReservados = new ArrayList<Asiento>();
		this.listaAsientosReservados.add(asientoSobreReservado);

	}
	
	@Test
	public void testUsuarioGratuitoReserva(){
		try{
			this.gratuito.reservar(this.listaAsientosAReservar);
		}
		catch(Exception e){
			
			final String msg = "Este tipo de usuario no puede reservar asientos";
		    assertEquals(msg, e.getMessage());	
		}
	}
	
	@Test
	public void testUsuarioVIPReserva(){
		
		this.vip.reservar(this.listaAsientosAReservar);
		Integer cantAsientosReservados = 0;
		
		for (Asiento asiento: this.listaAsientosAReservar) {	
			for(Reserva reserva: asiento.getReservas()){
				if(reserva.getUsuario().equals(this.vip)){
					cantAsientosReservados++;
				}
			}
		}		
		assertEquals(cantAsientosReservados, new Integer(2));
	}
	
	@Test
	public void testUsuarioStandarReserva(){
		
		this.standar.reservar(this.listaAsientosAReservar);
		Integer cantAsientosReservados = 0;
		
		for (Asiento asiento: this.listaAsientosAReservar) {	
			for(Reserva reserva: asiento.getReservas()){
				if(reserva.getUsuario().equals(this.standar)){
					cantAsientosReservados++;
				}
			}
		}		
		assertEquals(cantAsientosReservados, new Integer(2));
	}
	
	@Test
	public void testIsAsientoSobreReservado(){
		
		this.standar.reservar(this.listaAsientosSobreReservados);
		this.vip.reservar(this.listaAsientosSobreReservados);
		
		Asiento asiento = this.listaAsientosSobreReservados.get(0);

		assertTrue(asiento.getReservas().size()==2);
	}
	
	@Test
	public void testComprarAsientoReservadoPorOtroUsuario(){
		
		this.standar.reservar(this.listaAsientosAComprar);
		
		Itinerario itinerario = new Itinerario();
		itinerario.addAsiento(this.listaAsientosAComprar.get(0));
		
		try{
			this.vip.Comprar(itinerario);			
		}
		catch(Exception e){
			final String msg = "Este asiento fue reservado por otra persona";
			assertEquals(msg, e.getMessage());	
		}	
	}
	
	@Test
	public void testComprarAsientoReservadoPorMismoUsuario(){
		
		this.standar.reservar(this.listaAsientosAComprar);
		
		Itinerario itinerario = new Itinerario();
		itinerario.addAsiento(this.listaAsientosAComprar.get(0));
		
		this.standar.Comprar(itinerario);	
		
		assertTrue(this.listaAsientosAComprar.size()==0);	
	}
	
	@Test
	public void testTransferenciaReserva(){
				
		this.standar.reservar(this.listaAsientosReservados);
		this.vip.reservar(this.listaAsientosReservados);
		
		Asiento asientoSobreReservado = this.listaAsientosReservados.get(0);
		
		asientoSobreReservado.transferirReserva();
		
		assertEquals(asientoSobreReservado.getReservas().peek().getUsuario().getDNI(),this.vip.getDNI());
	}
	
}
